Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add BmadQuadrupole element #153

Merged
merged 39 commits into from
Jul 24, 2024
Merged

Conversation

jp-ga
Copy link
Collaborator

@jp-ga jp-ga commented May 8, 2024

Description

Add BmadQuadrupole element by interfacing with Bmad-X tracking routines.

Motivation and Context

Closes #139

  • I have raised an issue to propose this change (required for new features and bug fixes)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation (update in the documentation)

Checklist

  • I have updated the changelog accordingly (required).
  • My change requires a change to the documentation.
  • I have updated the tests accordingly (required for a bug fix or a new feature).
  • I have updated the documentation accordingly.
  • I have reformatted the code and checked that formatting passes (required).
  • I have have fixed all issues found by flake8 (required).
  • I have ensured that all pytest tests pass (required).
  • I have run pytest on a machine with a CUDA GPU and made sure all tests pass (required).
  • I have checked that the documentation builds (required).

Note: We are using a maximum length of 88 characters per line.

@jp-ga jp-ga added the enhancement New feature or request label May 8, 2024
@jp-ga jp-ga requested a review from jank324 May 8, 2024 18:55
@jp-ga jp-ga self-assigned this May 8, 2024
@jp-ga jp-ga linked an issue May 8, 2024 that may be closed by this pull request
@jp-ga jp-ga marked this pull request as draft May 8, 2024 19:05
cheetah/accelerator.py Outdated Show resolved Hide resolved
cheetah/bmadx/interface.py Outdated Show resolved Hide resolved
@jank324
Copy link
Member

jank324 commented May 14, 2024

As a general comment. I'm not sure I like this quick-and-dirty drop-in way of integrating Bmad-X elements. However, I think it makes sense to test them this way. In the long-term we should think about how this can be clean up better.

Some questions we should ask ourselves:

  • Do we really want a separate bmadx module? This means that code is suddenly in a very different place than the other tracking code.
  • Should there be a single Quadrupole class that has something like a tracking_method: Literal["linear", "bmadx"] argument?

Maybe slightly unrelated but I saw it in this PR:

  • I think it's not very nice to have something like C = scipy.constants.speed_of_light at the top of a file. Ideally, one would just from scripy.constants import speed_of_light and use that. I think this might cause issues sometimes, when a torch.Tensor is strictly needed, but I cannot produce an example right now. Maybe we should add a cheetah.constants module that takes scripy.constnts and always returns torch.Tensors. But again, I'm not sure we actually need that ... just something to think about.

@jp-ga jp-ga marked this pull request as ready for review June 20, 2024 19:28
@jank324 jank324 requested review from cr-xu and jank324 June 20, 2024 19:36
@jp-ga
Copy link
Collaborator Author

jp-ga commented Jun 20, 2024

One small thing to keep in mind, bmadx tracking agrees to single precision with bmadx. I was expecting it to agree to double precision, but it is good enough for now.

Comment on lines 4 to 35
def cheetah_to_bmad_coords(
cheetah_coords: torch.Tensor, ref_energy: torch.Tensor, mc2: torch.Tensor
) -> torch.Tensor:
"""Transforms Cheetah coordinates to Bmad coordinates.
:param cheetah_coords: 7-dimensional particle vectors in Cheetah coordinates.
:param ref_energy: reference energy in eV.
"""
# initialize Bmad coordinates:
bmad_coords = cheetah_coords[..., :6].clone()

# Cheetah longitudinal coords:
tau = cheetah_coords[..., 4]
delta = cheetah_coords[..., 5]

# compute p0c and bmad z, pz
p0c = torch.sqrt(ref_energy**2 - mc2**2)
energy = ref_energy + delta * p0c
p = torch.sqrt(energy**2 - mc2**2)
beta = p / energy
z = -beta * tau
pz = (p - p0c) / p0c

# Bmad coords:
bmad_coords[..., 4] = z
bmad_coords[..., 5] = pz

return bmad_coords, p0c


def bmad_to_cheetah_coords(
bmad_coords: torch.Tensor, p0c: torch.Tensor, mc2: torch.Tensor
) -> torch.Tensor:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to just integrate these two methods also in ParticleBeam like the other transformations?
I think p0c can also be provided as a property.

Copy link
Collaborator Author

@jp-ga jp-ga Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to include the coordinate transforms in here instead: https://github.com/desy-ml/cheetah/blob/master/cheetah/converters/bmad.py

This way it could also be used to transform beams for both Bmad and Bmad-X.

Any thoughts?

cheetah/bmadx_utils.py Outdated Show resolved Hide resolved
cheetah/bmadx_utils.py Outdated Show resolved Hide resolved
cheetah/accelerator/quadrupole.py Outdated Show resolved Hide resolved
@jank324
Copy link
Member

jank324 commented Jun 25, 2024

@jp-ga, the question came up with @roussel-ryan, if this or #163 should be merged first. I think a main question in that was if the changes in #163 might make conversions in this PR redundant. Do you have an opinion on this?

Copy link
Member

@jank324 jank324 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jp-ga Can you have a brief look at the split function I wrote a comment about?

@roussel-ryan Can you check if the test I added seems to be about the error you ran into?

Otherwise, I think this is ready to merge!

@jp-ga
Copy link
Collaborator Author

jp-ga commented Jul 22, 2024

I'm not sure if we should add now how Quadrupole.split handles the num_steps argument.

@jank324 I thought about this back when developing Bmad-X, and at the end I decided that it was better to keep the number of steps in the quad different and independent from the number of elements when splitting. For example, if you have a quad with num_steps=3 and you split the element in 5, the code should do 5 quadrupoles with L/5 length, each of which with num_steps=3 (doing 3 drift-kick-drift steps).

In the future I would like to implement fringe fields, so the splitting should have entrance fringe at the first element's entrance and exit fringe at the last element's exit, but we can leave this for a future PR.

@jank324
Copy link
Member

jank324 commented Jul 22, 2024

I'm not sure if we should add now how Quadrupole.split handles the num_steps argument.

@jank324 I thought about this back when developing Bmad-X, and at the end I decided that it was better to keep the number of steps in the quad different and independent from the number of elements when splitting. For example, if you have a quad with num_steps=3 and you split the element in 5, the code should do 5 quadrupoles with L/5 length, each of which with num_steps=3 (doing 3 drift-kick-drift steps).

In the future I would like to implement fringe fields, so the splitting should have entrance fringe at the first element's entrance and exit fringe at the last element's exit, but we can leave this for a future PR.

@jp-ga So the behaviour you would like to have now is that each of the 5 child quadrupoles has 3 splits, just like their parent had 3 splits? In that case, don't we need to add the line highlighted below in the split method?

element = Quadrupole(
    torch.min(resolution, remaining),
    self.k1,
    misalignment=self.misalignment,
    tilt=self.tilt,
    num_steps=self.num_steps,   # <-- Add this line?
    dtype=self.length.dtype,
    device=self.length.device,
)

@roussel-ryan
Copy link

roussel-ryan commented Jul 22, 2024

@jank324 I'm not sure if the test you added will raise the issue I ran into, I think my error had to do with the ellipsoid beam generation, but I'm not sure if that test will run into the same issue. I think it may be likely through since I remember that the different methods used the same code

@jp-ga
Copy link
Collaborator Author

jp-ga commented Jul 22, 2024

I'm not sure if we should add now how Quadrupole.split handles the num_steps argument.

@jank324 I thought about this back when developing Bmad-X, and at the end I decided that it was better to keep the number of steps in the quad different and independent from the number of elements when splitting. For example, if you have a quad with num_steps=3 and you split the element in 5, the code should do 5 quadrupoles with L/5 length, each of which with num_steps=3 (doing 3 drift-kick-drift steps).
In the future I would like to implement fringe fields, so the splitting should have entrance fringe at the first element's entrance and exit fringe at the last element's exit, but we can leave this for a future PR.

@jp-ga So the behaviour you would like to have now is that each of the 5 child quadrupoles has 3 splits, just like their parent had 3 splits? In that case, don't we need to add the line highlighted below in the split method?

element = Quadrupole(
    torch.min(resolution, remaining),
    self.k1,
    misalignment=self.misalignment,
    tilt=self.tilt,
    num_steps=self.num_steps,   # <-- Add this line?
    dtype=self.length.dtype,
    device=self.length.device,
)

@jank324 Exactly, I will add it soon.

@jank324 jank324 requested a review from cr-xu July 22, 2024 22:07
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
cheetah/utils/bmadx.py Show resolved Hide resolved
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
cheetah/utils/bmadx.py Outdated Show resolved Hide resolved
Copy link
Member

@cr-xu cr-xu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One final comment: Is it intended to keep the dev/ folder? If the notebook is useful, shall we move it to some other places, like a documentation page?
Otherwise it's good to go!

@jank324
Copy link
Member

jank324 commented Jul 23, 2024

One final comment: Is it intended to keep the dev/ folder? If the notebook is useful, shall we move it to some other places, like a documentation page? Otherwise it's good to go!

I'm also not sure about the dev/ folder. I left it because I also sometimes write notebooks to develop features and I often worry that I will have to write them twice because I always delete them at some point once I'm done and I never commit them. dev/ would be a clean way to keep them around.

On the other hand, I've never actually felt like I needed to rewrite a notebook for some reason and we might not want to clutter up the repository and history like this.

@jank324
Copy link
Member

jank324 commented Jul 24, 2024

So ... to document the decision: The dev/ folder remains for now, but the long-term goal should be to not have it. Interesting examples should instead, for example, appear in the documentation.

@jank324 jank324 merged commit 301935a into master Jul 24, 2024
15 checks passed
@jank324 jank324 deleted the 139-add-quadrupole-with-chromatic-effects branch July 24, 2024 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add quadrupole with chromatic effects
4 participants